Skip to main content
Version: 2.x.x

Testing

Introduction

Testing is one of the best things in Hyper Fetch. With our architecture and focus on global singleton structure, tests can be largely based on the application’s configuration. This means tests are no longer sensitive to micro-changes (like changing endpoints or types). Everything reacts and adapts to tests or shows the appropriate error – making tests easier to maintain and faster to write.


Benefits

  • Our setup is always up-to-date with the production solution.
  • No configuration or setup duplication.
  • Easy test maintenance.
  • Faster test builds.

Isolation

The Builder can become a global module, which will cause it to get mixed between test cases from different files if we run them in many workers. Thus, we need to isolate it. This takes two steps:

  1. Clear the Builder

Use the built-in method .clear() to ensure builder submodules are initialized and clear of any changes.

  1. Clear the node / runner cache

As you would with Jest, use the built-in method .resetModules() to clean the builder global module and reinitialize it. Depending on the libraries used, you can check out your environment runner methods or try libraries like decache.


Example

In this example, we’re using the great mocking libraries msw and testing-library, but this solution works with other libraries like Cypress. This allows us to simulate real requests and make our tests as close to the production environment as possible. We can thus create a really powerful flow that allows us to easily develop tests.

You can build a utilities set that takes a command and uses its method, endpoint and types to create functions that allow you to intercept requests.

import { builder } from "../api/builder";
import { getUsers } from "../api";

// 'createInterceptor' is some custom method for handling intercepting in the tests we write
// In our internal test we used MSW as main intercepting layer
const getUsersInterceptor = createInterceptor(getUsers, {
data: [
{ name: "John", age: 18 },
{ name: "Matthew", age: 27 },
],
});

beforeEach(() => {
// We need to reset modules cache as builder is globally exported module
// This way it will not get mixed-up with other test cases running in parallel
jest.resetModules();
// Clean the environment to make sure it's isolated
builder.clear();
});

it("My test", async () => {
// Start interceptor listener
const mock = getUsersInterceptor();

// Handle test
renderApp();
expect(await screen.findByText(mock.data[0])).toBeVisible();
});